package cn.dlc.com.linear;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Iterator;

/**
 * @author 邓立川
 * @date 2021/3/21 10:00
 * @desc 当前类的描述信息
 */
@Data
public class TwoWayLinkList<T> implements Iterable<T>{

    // 第一个节点
    public Node<T> head;

    // 最后一个节点
    private Node<T> last;

    // 元素个数
    private int num;

    @AllArgsConstructor
    @NoArgsConstructor
    @Data
    private class Node<T> {
        private T item;
        private Node<T> pre;
        private Node<T> next;
    }

    // 构造函数初始化
    public TwoWayLinkList(){
        this.head = new Node<T>(null,null,null);
        this.num = 0;
        this.last = null;
    }

    // 置空
    public void clear(){
        this.num = 0;
        this.head.next = null;
        this.last = null;
    }

    // 长度
    public int length(){
        return num;
    }

    // 是否为空
    public boolean isEmpty(){
        return num == 0;
    }

    // 获取第一个元素
    public T first(){
        if(isEmpty()) {
            return null;
        }
        return head.next.getItem();
    }

    // 获取最后一个元素
    public T last(){
        if(isEmpty()) {
            return null;
        }
        return last.getItem();
    }

    // 最后插入
    public void insert(T t){
        // 判断是不是空的
        if(isEmpty()) {
            // 直接和head关联
            Node<T> newNode = new Node<>(t, this.head, null);
            this.head.next = newNode;
            this.last = newNode;
        } else {
            // 创建这个元素
            Node<T> newNode = new Node<>(t, this.last, null);
            // 获取到最后一个元素
            this.last.next = newNode;
            this.last = newNode;
        }

        // 元素加1
        this.num++;
    }

    // 指定位置插入
    public void insert(int i, T t) {

        // 找到i的元素
        Node<T> oldCurr = head;
        for (int j = 0; j <= i; j++) {
            oldCurr  = oldCurr.next;
        }

        // 前一个元素
        Node<T> pre = oldCurr.getPre();
        // 待插入的元素 ，前一个元素是pre，后一个元素是原来i处的元素
        Node<T> newCurrNode = new Node<>(t, pre, oldCurr);
        // 前一个元素指向这个t，同时t指向temp（也就是原来这个位置的元素）
        pre.setNext(newCurrNode);
        // 原来这个位置的元素temp指向当前元素
        oldCurr.setPre(newCurrNode);

        // 元素个数+1
        this.num++;
    }

    // 获取指定位置的元素
    public T get(int i) {
        if(isEmpty())  {
            return null;
        }

        // 找到i的元素
        Node<T> oldCurr = head;
        for (int j = 0; j <= i; j++) {
            oldCurr  = oldCurr.next;
        }

        return oldCurr.getItem();
    }

    // 元素首次出现的索引
    public int indexOf(T t) {

        Node<T> node = head;
        for (int j = 0; j < this.num; j++) {
            node  = node.next;
            if(node.getItem().equals(t)) {
                return j;
            }
        }
        return -1;
    }

    //  删除指定 位置的元素，并且返回
    public T remove(int i) {

        // node为指定位置的元素
        Node<T> node = head;
        for (int j = 0; j < i; j++) {
            node  = node.next;
        }

        // 待删除元素的前一个元素
        Node<T> pre = node.getPre();
        //  待删除元素的后一个 元素
        Node<T> next = node.getNext();
        pre.setNext(next);
        next.setPre(pre);

        this.num--;

        return node.getItem();
    }


    @Override
    public Iterator<T> iterator() {
        return new TIterator();
    }

    private class TIterator implements Iterator<T>{

        private Node<T> n;

        public TIterator(){
            this.n = head;
        }

        @Override
        public boolean hasNext() {
            return n.getNext() != null;
        }

        @Override
        public T next() {
            // 一定要重新给n赋值
            n = n.getNext();
            return n.getItem();
        }
    }
}
